﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Microsoft.Mtool.FSM;
using System.Xml;
using System.Xml.Serialization;

namespace MToolStudio.Render
{
    [Serializable]
    public class FunctionR : IActionRenderable
    {
        private Action action;
        private Point position;
        private string name;

        /// <summary>
        /// for xml serialization use only
        /// </summary>
        public FunctionR()
        { }

        public FunctionR(Point initialPos, string name)
        {
            position = initialPos;
            this.name = name;
            action = new Action();
            action.Id = name;
        }

        [XmlElement]
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        [XmlElement]
        public Action InnerAction
        {
            get { return action; }
            set { action = value; }
        }

        [XmlElement]
        public Point Position
        {
            get { return position; }
            set { position = value; }
        }

        /// <summary>
        /// the main paint method
        /// </summary>
        /// <param name="g"></param>
        public void Paint(Graphics g)
        {
            g.DrawEllipse(RenderConstants.FunctionCirclePen, position.X - RenderConstants.FunctionCircleRadius,
                position.Y - RenderConstants.FunctionCircleRadius, RenderConstants.FunctionCircleRadius*2, 
                RenderConstants.FunctionCircleRadius*2);

            g.DrawLine(RenderConstants.FunctionLinePen, new Point(position.X - RenderConstants.FunctionHalfLength, position.Y),
                new Point(position.X + RenderConstants.FunctionHalfLength, position.Y));

            g.DrawString(name, RenderConstants.FunctionFont, RenderConstants.FunctionBrush, position.X, position.Y);
        }

        /// <summary>
        /// paint method to be called before any other paint being called
        /// </summary>
        /// <param name="g"></param>
        public void PrePaint(Graphics g)
        { }

        /// <summary>
        /// paint method to be called after all the other main paint being called
        /// </summary>
        /// <param name="g"></param>
        public void PostPaint(Graphics g)
        { 
        }

        /// <summary>
        /// paint method to be called if this object is focused
        /// </summary>
        /// <param name="g"></param>
        public void PaintFocus(Graphics g)
        {
            int focusedRadius = RenderConstants.FunctionCircleRadius + 2;
            g.DrawEllipse(RenderConstants.FunctionCirclePen, position.X - focusedRadius,
                position.Y - focusedRadius, focusedRadius * 2, focusedRadius * 2);

            g.DrawLine(RenderConstants.FunctionLinePen, new Point(position.X - RenderConstants.FunctionHalfLength, position.Y),
                new Point(position.X + RenderConstants.FunctionHalfLength, position.Y));

            g.DrawString(name, RenderConstants.FunctionFont, RenderConstants.FunctionBrush, position.X, position.Y);
        }

        /// <summary>
        /// checks whether the current renderable object is selected
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public bool IsSelected(Point p)
        {
            if (p.X > position.X - RenderConstants.FunctionHalfLength && p.X < position.X + RenderConstants.FunctionHalfLength)
            {
                if (Math.Abs(p.Y - position.Y) < RenderConstants.FunctionSelectThresholdY)
                    return true;
            }
            return false;
        }
    }
}
